package com.googlecode.svnj.reports;

import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;

import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;

import org.apache.jackrabbit.webdav.DavException;
import org.apache.jackrabbit.webdav.DavResource;
import org.apache.jackrabbit.webdav.WebdavRequest;
import org.apache.jackrabbit.webdav.WebdavResponse;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import com.googlecode.svnj.RepoContext;
import com.googlecode.svnj.XMLUtil;
import com.googlecode.svnj.dav.IO;
import com.googlecode.svnj.dav.Path;
import com.googlecode.svnj.dav.SVNResource;

public class MergeinfoReport extends ReportRequest {

    private List<String> paths = new ArrayList<String>();
    private long revision = -1;
    private boolean includeDescendents = false;
    private int inheritance = IN_EXPLICIT;
    @Override
    public String getReportType() {
        return TYPE_MERGEINFO;
    }
/*
 <S:mergeinfo-report xmlns:S="svn:">
  <S:revision>4</S:revision>
  <S:inherit>inherited</S:inherit>
  <S:include-descendants>yes</S:include-descendants>
  <S:path>branches/1.0</S:path>
 </S:mergeinfo-report>
--------------------------
<S:mergeinfo-report xmlns:S="svn:">
 <S:revision>0</S:revision>
 <S:inherit>explicit</S:inherit>
 <S:path></S:path>
</S:mergeinfo-report>
 */
    @Override
    protected void parse(Node root) {
        // walk elements
        NodeList children = root.getChildNodes();
        for (int i = 0; i < children.getLength(); i++) {
            Node n = children.item(i);
            String name = n.getLocalName();
            if ("revision".equals(name)) {
                this.revision = Long.parseLong(n.getTextContent());
            } else if ("include-descendents".equals(name)) {
                String txt = n.getTextContent();
                this.includeDescendents =
                    ("yes".equalsIgnoreCase(txt) || "true".equalsIgnoreCase(txt));
            } else if ("inherit".equals(name)) {
                this.inheritance = parseInheritance(n.getTextContent());
            } else if ("path".equals(name)) {
                paths.add(n.getTextContent());
            }
        }        
    }

    @Override
    public void report(WebdavRequest req, WebdavResponse rsp,
            DavResource resource) throws DavException, IOException,
            XMLStreamException {
        rsp.setHeader("Content-Type", "text/xml; charset=\"utf-8\"");
        OutputStream os = rsp.getOutputStream();
        XMLStreamWriter xs = XMLUtil.initWriter(os, "S:mergeinfo-report");
        RepoContext rc = IO.get().getRepo(req);
        String[] pa = (String[]) paths.toArray(new String[0]);
        // make them all full paths
        SVNResource svnRes = (SVNResource) resource;
        String reposPath = svnRes.getSpecialResource().getReposPath();
        if (reposPath != null) {
            for (int i = 0; i < pa.length; i++)
                pa[i] = Path.join(reposPath, pa[i]);
        }
        xs.writeEndDocument(); // be sure to close it out        
    }

    /* enum svn_mergeinfo_inheritance_t */
    public static final int IN_EXPLICIT = 0; 
    public static final int IN_INHERITED = 1; 
    public static final int IN_NEAREST_ANCESTOR = 2;
    /* svn_inheritance_from_word(char*) */
    private int parseInheritance(String in) {
        if ("inherited".equals(in))
            return IN_INHERITED;
        if ("nearest-ancestor".equals(in))
            return IN_NEAREST_ANCESTOR;
        return IN_EXPLICIT;
    }
}
